home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 2010 Software/Programs / PCGuia_programas.iso / Software / Utils / The GIMP / gimp-2.6.8-i686-setup.exe / {app} / lib / gimp / 2.0 / plug-ins / py-slice.py < prev    next >
Encoding:
Python Source  |  2009-12-15  |  15.1 KB  |  455 lines

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. #Copyright (c) Manish Singh
  5. #javascript animation support by Joao S. O. Bueno Calligaris (2004)
  6.  
  7. #   Gimp-Python - allows the writing of Gimp plugins in Python.
  8. #   Copyright (C) 2003, 2005  Manish Singh <yosh@gimp.org>
  9. #
  10. #   This program is free software; you can redistribute it and/or modify
  11. #   it under the terms of the GNU General Public License as published by
  12. #   the Free Software Foundation; either version 2 of the License, or
  13. #   (at your option) any later version.
  14. #
  15. #   This program is distributed in the hope that it will be useful,
  16. #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. #   GNU General Public License for more details.
  19. #
  20. #   You should have received a copy of the GNU General Public License
  21. #   along with this program; if not, write to the Free Software
  22. #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  
  24. # (c) 2003 Manish Singh.
  25. #"Guillotine implemented ala python, with html output
  26. # (based on perlotine by Seth Burgess)",
  27. # Modified by Jo├úo S. O. Bueno Calligaris to allow  dhtml animations (2005)
  28.  
  29. import os
  30.  
  31. from gimpfu import *
  32. import os.path
  33.  
  34. gettext.install("gimp20-python", gimp.locale_directory, unicode=True)
  35.  
  36. def pyslice(image, drawable, save_path, html_filename,
  37.             image_basename, image_extension, separate,
  38.             image_path, cellspacing, animate, skip_caps):
  39.     if animate:
  40.         count = 0
  41.         drw = []
  42.         #image.layers is a reversed list of the layers on the image
  43.         #so, count indexes from number of layers to 0.
  44.         for i in xrange (len (image.layers) -1, -1, -1):
  45.             if image.layers[i].visible:
  46.                 drw.append(image.layers[i])
  47.                 count += 1
  48.                 if count == 3:
  49.                     break
  50.  
  51.  
  52.     vert, horz = get_guides(image)
  53.  
  54.     if len(vert) == 0 and len(horz) == 0:
  55.         return
  56.  
  57.     gimp.progress_init(_("Slice"))
  58.     progress_increment = 1 / ((len(horz) + 1) * (len(vert) + 1))
  59.     progress = 0.0
  60.  
  61.     def check_path(path):
  62.         path = os.path.abspath(path)
  63.  
  64.         if not os.path.exists(path):
  65.             os.mkdir(path)
  66.  
  67.         return path
  68.  
  69.     save_path = check_path(save_path)
  70.  
  71.     if not os.path.isdir(save_path):
  72.         save_path = os.path.dirname(save_path)
  73.  
  74.     if separate:
  75.         image_relative_path = image_path
  76.         if not image_relative_path.endswith("/"):
  77.             image_relative_path += "/"
  78.         image_path = check_path(os.path.join(save_path, image_path))
  79.     else:
  80.         image_relative_path = ''
  81.         image_path = save_path
  82.  
  83.     tw = TableWriter(os.path.join(save_path, html_filename),
  84.                      cellspacing=cellspacing, animate=animate)
  85.  
  86.     top = 0
  87.  
  88.     for i in range(0, len(horz) + 1):
  89.         if i == len(horz):
  90.             bottom = image.height
  91.         else:
  92.             bottom = image.get_guide_position(horz[i])
  93.  
  94.         tw.row_start()
  95.  
  96.         left = 0
  97.  
  98.         for j in range(0, len(vert) + 1):
  99.             if j == len(vert):
  100.                 right = image.width
  101.             else:
  102.                 right = image.get_guide_position(vert[j])
  103.             if (skip_caps   and
  104.                  (
  105.                    (len(horz) >= 2 and (i == 0 or i == len(horz) )) or
  106.                    (len(vert) >= 2 and (j == 0 or j == len(vert) ))
  107.                  )
  108.                ):
  109.                 skip_stub = True
  110.             else:
  111.                 skip_stub = False
  112.  
  113.             if (not animate or skip_stub):
  114.                 src = (image_relative_path +
  115.                        slice (image, None, image_path,
  116.                               image_basename, image_extension,
  117.                               left, right, top, bottom, i, j, ""))
  118.             else:
  119.                 src = []
  120.                 for layer, postfix in zip (drw, ("", "hover", "clicked")):
  121.                     src.append (image_relative_path +
  122.                                 slice(image, layer, image_path,
  123.                                       image_basename, image_extension,
  124.                                       left, right, top, bottom, i, j, postfix))
  125.  
  126.             tw.cell(src, right - left, bottom - top, i, j, skip_stub)
  127.  
  128.             left = right + cellspacing
  129.  
  130.             progress += progress_increment
  131.             gimp.progress_update(progress)
  132.  
  133.         tw.row_end()
  134.  
  135.         top = bottom + cellspacing
  136.  
  137.     tw.close()
  138.  
  139. def slice(image, drawable, image_path, image_basename, image_extension,
  140.           left, right, top, bottom, i, j, postfix):
  141.     if postfix:
  142.         postfix = "_" + postfix
  143.     src = "%s_%d_%d%s.%s" % (image_basename, i, j, postfix, image_extension)
  144.     filename = os.path.join(image_path, src)
  145.  
  146.     if not drawable:
  147.         temp_image = image.duplicate()
  148.         temp_drawable = temp_image.active_layer
  149.     else:
  150.         if image.base_type == INDEXED:
  151.             #gimp_layer_new_from_drawable doesn't work for indexed images.
  152.             #(no colormap on new images)
  153.             original_active = image.active_layer
  154.             image.active_layer = drawable
  155.             temp_image = image.duplicate()
  156.             temp_drawable = temp_image.active_layer
  157.             image.active_layer = original_active
  158.             temp_image.disable_undo()
  159.             #remove all layers but the intended one
  160.             while len (temp_image.layers) > 1:
  161.                 if temp_image.layers[0] != temp_drawable:
  162.                     pdb.gimp_image_remove_layer (temp_image, temp_image.layers[0])
  163.                 else:
  164.                     pdb.gimp_image_remove_layer (temp_image, temp_image.layers[1])
  165.         else:
  166.             temp_image = pdb.gimp_image_new (drawable.width, drawable.height,
  167.                                          image.base_type)
  168.             temp_drawable = pdb.gimp_layer_new_from_drawable (drawable, temp_image)
  169.             temp_image.add_layer (temp_drawable, -1)
  170.  
  171.     temp_image.disable_undo()
  172.     temp_image.crop(right - left, bottom - top, left, top)
  173.     if image_extension == "gif" and image.base_type == RGB:
  174.         pdb.gimp_image_convert_indexed (temp_image,NO_DITHER, MAKE_PALETTE, 255,
  175.                                         True, False, False)
  176.     if image_extension == "jpg" and image.base_type == INDEXED:
  177.         pdb.gimp_image_convert_rgb (temp_image)
  178.  
  179.     pdb.gimp_file_save(temp_image, temp_drawable, filename, filename)
  180.  
  181.     gimp.delete(temp_image)
  182.     return src
  183.  
  184. class GuideIter:
  185.     def __init__(self, image):
  186.         self.image = image
  187.         self.guide = 0
  188.  
  189.     def __iter__(self):
  190.         return iter(self.next_guide, 0)
  191.  
  192.     def next_guide(self):
  193.         self.guide = self.image.find_next_guide(self.guide)
  194.         return self.guide
  195.  
  196. def get_guides(image):
  197.     vguides = []
  198.     hguides = []
  199.  
  200.     for guide in GuideIter(image):
  201.         orientation = image.get_guide_orientation(guide)
  202.  
  203.         guide_position = image.get_guide_position(guide)
  204.  
  205.         if guide_position > 0:
  206.             if orientation == ORIENTATION_VERTICAL:
  207.                 if guide_position < image.width:
  208.                     vguides.append((guide_position, guide))
  209.             elif orientation == ORIENTATION_HORIZONTAL:
  210.                 if guide_position < image.height:
  211.                     hguides.append((guide_position, guide))
  212.  
  213.     def position_sort(x, y):
  214.         return cmp(x[0], y[0])
  215.  
  216.     vguides.sort(position_sort)
  217.     hguides.sort(position_sort)
  218.  
  219.     vguides = [g[1] for g in vguides]
  220.     hguides = [g[1] for g in hguides]
  221.  
  222.     return vguides, hguides
  223.  
  224. class TableWriter:
  225.     def __init__(self, filename, cellpadding=0, cellspacing=0, border=0,
  226.                  animate=False):
  227.  
  228.         self.filename = filename
  229.         self.table_attrs = {}
  230.  
  231.         #Hellraisen IE 6 doesn't support CSS for table control.
  232.         self.table_attrs['cellpadding'] = cellpadding
  233.         self.table_attrs['cellspacing'] = cellspacing
  234.         self.table_attrs['border'] = border
  235.  
  236.         self.image_prefix = os.path.basename (filename)
  237.         self.image_prefix = self.image_prefix.split(".")[0]
  238.         self.image_prefix = self.image_prefix.replace ("-", "_")
  239.         self.image_prefix = self.image_prefix.replace (" ", "_")
  240.  
  241.  
  242.         if animate:
  243.             self.animate = True
  244.             self.images = []
  245.         else:
  246.             self.animate = False
  247.  
  248.         if os.path.exists (filename):
  249.             #The plug-in is running to overwrite a previous
  250.             #version of the file. This will parse the href targets already
  251.             #in the file to preserve them.
  252.             self.urls = self.parse_urls ()
  253.         else:
  254.             self.urls = []
  255.  
  256.         self.url_index = 0
  257.  
  258.         self.html = open(filename, 'wt')
  259.         self.open()
  260.  
  261.     def next_url (self):
  262.         if self.url_index < len (self.urls):
  263.             self.url_index += 1
  264.             return self.urls [self.url_index - 1]
  265.         else:
  266.             #Default url to use in the anchor tags:
  267.             return ("#")
  268.  
  269.     def write(self, s, vals=None):
  270.         if vals:
  271.             s = s % vals
  272.  
  273.         self.html.write(s + '\n')
  274.  
  275.     def open(self):
  276.         out = '''<!--HTML SNIPPET GENERATED BY GIMP
  277.  
  278. WARNING!! This is NOT a fully valid HTML document, it is rather a piece of
  279. HTML generated by GIMP's py-slice plugin that should be embedded in an HTML
  280. or XHTML document to be valid.
  281.  
  282. Replace the href targets in the anchor (<a >) for your URLS to have it working
  283. as a menu.
  284.  -->\n'''
  285.         out += '<table'
  286.  
  287.         for attr, value in self.table_attrs.iteritems():
  288.             out += ' %s="%s"' % (attr, value)
  289.  
  290.         out += '>'
  291.  
  292.         self.write(out)
  293.  
  294.     def close(self):
  295.         self.write('</table>\n')
  296.         prefix = self.image_prefix
  297.         if self.animate:
  298.             out = """
  299. <script language="javascript" type="text/javascript">
  300. /* Made with GIMP */
  301.  
  302. /* Preload images: */
  303.     images_%s = new Array();
  304.                    \n"""    % prefix
  305.             for image in self.images:
  306.                 for type_ in ("plain", "hover", "clicked"):
  307.                     if image.has_key(type_):
  308.                         image_index = ("%d_%d_%s" %
  309.                                        (image["index"][0],
  310.                                         image["index"][1], type_))
  311.                         out += ("    images_%s[\"%s\"] = new  Image();\n" %
  312.                                 (prefix, image_index))
  313.                         out += ("    images_%s[\"%s\"].src = \"%s\";\n" %
  314.                             (prefix, image_index, image[type_]))
  315.  
  316.             out+= """
  317. function exchange (image, images_array_name, event)
  318.   {
  319.     name = image.name;
  320.     images = eval (images_array_name);
  321.  
  322.     switch (event)
  323.       {
  324.         case 0:
  325.           image.src = images[name + "_plain"].src;
  326.           break;
  327.         case 1:
  328.           image.src = images[name + "_hover"].src;
  329.           break;
  330.         case 2:
  331.           image.src = images[name + "_clicked"].src;
  332.           break;
  333.         case 3:
  334.           image.src = images[name + "_hover"].src;
  335.           break;
  336.       }
  337.  
  338.   }
  339. </script>
  340. <!--
  341. End of the part generated by GIMP
  342. -->
  343. """
  344.             self.write (out)
  345.  
  346.  
  347.     def row_start(self):
  348.         self.write('  <tr>')
  349.  
  350.     def row_end(self):
  351.         self.write('</tr>\n')
  352.  
  353.     def cell(self, src, width, height, row=0, col=0, skip_stub = False):
  354.         if isinstance (src, list):
  355.             prefix = "images_%s" % self.image_prefix
  356.             self.images.append ({"index" : (row, col), "plain" : src[0]})
  357.  
  358.             out = ('    <td><a href="%s"><img alt="" src="%s" ' +
  359.                   'style="width: %dpx; height: %dpx; border-width: 0px" \n') %\
  360.                   (self.next_url(), src[0], width, height)
  361.             out += 'name="%d_%d" \n' % (row, col)
  362.             if len(src) >= 2:
  363.                 self.images[-1]["hover"] = src [1]
  364.                 out += """      onmouseout="exchange(this, '%s', 0);"\n""" % \
  365.                        prefix
  366.                 out += """      onmouseover="exchange(this, '%s', 1);"\n""" % \
  367.                        prefix
  368.             if len(src) >= 3:
  369.                 self.images[-1]["clicked"] = src [2]
  370.                 out += """      onmousedown="exchange(this, '%s', 2);"\n""" % \
  371.                        prefix
  372.                 out += """      onmouseup="exchange(this, '%s', 3);"\n""" % \
  373.                        prefix
  374.  
  375.  
  376.  
  377.             out += "/></a></td>\n"
  378.  
  379.         else:
  380.             if skip_stub:
  381.                 out =  ('    <td><img alt=" " src="%s" style="width: %dpx; ' +
  382.                         ' height: %dpx; border-width: 0px;"></td>') % \
  383.                         (src, width, height)
  384.             else:
  385.                 out = ('    <td><a href="#"><img alt=" " src="%s" ' +
  386.                       ' style="width: %dpx; height: %dpx; border-width: 0px;">' +
  387.                       '</a></td>') %  (src, width, height)
  388.         self.write(out)
  389.     def parse_urls (self):
  390.         """
  391.            This will parse any url targets in the href="XX" fields
  392.            of the given file and return then as a list
  393.         """
  394.         import re
  395.         url_list = []
  396.         try:
  397.             html_file = open (self.filename)
  398.  
  399.             # Regular expression to pick everything up to the next
  400.             # doublequote character after finding the sequence 'href="'.
  401.             # The found sequences will be returned as a list by the
  402.             # "findall" method.
  403.             expr = re.compile (r"""href\=\"([^\"]*?)\"""")
  404.             url_list = expr.findall (html_file.read (2 ** 18))
  405.             html_file.close()
  406.  
  407.         except:
  408.             # silently ignore any errors parsing this. The file being
  409.             # overwritten may not be a file created by py-slice.
  410.             pass
  411.  
  412.         return url_list
  413.  
  414.  
  415. register(
  416.     "python-fu-slice",
  417.     # table snippet means a small piece of HTML code here
  418.     N_("Cuts an image along its guides, creates images and a HTML table snippet"),
  419.     """Add guides to an image. Then run this. It will cut along the guides,
  420.     and give you the html to reassemble the resulting images. If you
  421.     choose to generate javascript for onmouseover and clicked events, it
  422.     will use the lower three visible layers on the image for normal,
  423.     onmouseover and clicked states, in that order. If skip caps is
  424.     enabled, table cells on the edge of the table won't become animated,
  425.     and its images will be taken from the active layer.""",
  426.     "Manish Singh",
  427.     "Manish Singh",
  428.     "2003",
  429.     _("_Slice..."),
  430.     "*",
  431.     [
  432.         (PF_IMAGE, "image", "Input image", None),
  433.         (PF_DRAWABLE, "drawable", "Input drawable", None),
  434.         (PF_DIRNAME, "save-path",     _("Path for HTML export"), os.getcwd()),
  435.         (PF_STRING, "html-filename",  _("Filename for export"),  "slice.html"),
  436.         (PF_STRING, "image-basename", _("Image name prefix"),    "slice"),
  437.         (PF_RADIO, "image-extension", _("Image format"),         "gif", (("gif", "gif"), ("jpg", "jpg"), ("png", "png"))),
  438.         (PF_TOGGLE, "separate-image-dir",  _("Separate image folder"),
  439.          False),
  440.         (PF_STRING, "relative-image-path", _("Folder for image export"), "images"),
  441.         (PF_SPINNER, "cellspacing", _("Space between table elements"), 0,
  442.         (0,15,1)),
  443.         (PF_TOGGLE, "animate",      _("Javascript for onmouseover and clicked"),
  444.          False),
  445.         # table caps are table cells on the edge of the table
  446.         (PF_TOGGLE, "skip-caps",    _("Skip animation for table caps"), True)
  447.     ],
  448.     [],
  449.     pyslice,
  450.     menu="<Image>/Filters/Web",
  451.     domain=("gimp20-python", gimp.locale_directory)
  452.     )
  453.  
  454. main()
  455.